package myJs.tool

import cats.effect.IO
import myJs.Utils._

import scala.scalajs.js.Dynamic.{global => g}
import shared.Pojo._
import upickle.default._

import scala.scalajs.js

/** Created by yz on 27/7/2020
  */
object Pojo {

  val softs = List(
    PreDealSoft,
    AnnoSoft,
    PcaSoft,
    DiffAnaSoft,
    DiffAnaMulSoft,
    CcaRdaSoft,
    HeatmapSoft,
    PlsdaSoft,
    OplsdaSoft,
    BasicSoft,
    ZScoreSoft,
    BoxplotSoft,
    ViolinPlotSoft,
    BiomarkerSoft,
    KeggEnrichSoft,
    IPathSoft,
    EnrichSoft,
    ParCorSoft,
    MetMicCorSoft,
    DiagnoseSoft,
    RfSoft,
    SvmSoft,
    BorutaSoft,
    VennSoft,
    PreprocessSoft,
    LefseAnaSoft,
    LimmaAnaSoft,
    StampSoft,
    HorizontalBoxplotSoft
  )
  val sortedSofts = List(
    PreDealSoft,
    PreprocessSoft,
    BorutaSoft,
    SvmSoft,
    RfSoft,
    DiagnoseSoft,
    MetMicCorSoft,
    ParCorSoft,
    EnrichSoft,
    IPathSoft,
    KeggEnrichSoft,
    ViolinPlotSoft,
    BoxplotSoft,
    VennSoft,
    ZScoreSoft,
    BasicSoft,
    AnnoSoft,
    PcaSoft,
    OplsdaSoft,
    PlsdaSoft,
    HeatmapSoft,
    CcaRdaSoft,
    DiffAnaMulSoft,
    DiffAnaSoft,
    LefseAnaSoft,
    LimmaAnaSoft,
    StampSoft,
    HorizontalBoxplotSoft
  )
  val rPlots = List(
    GroupBarF,
    SampleBarF,
    VolcanoF,
    ClassCountPieF,
    StatPieF,
    RfPlot,
    SvmPlot,
    BorutaBox
  )
  val workflows = List(DataPreprocessWorkflow, FeatureSelectionWorkflow)

  case class FilterContentData(fieldName: String, label: String, values: List[String] = List[String]())

  object PcaBoxplot extends PcaBoxplotT

  object PlsdaBoxplot extends PlsdaBoxplotT

  object GroupBarF extends GroupBarT

  object SampleBarF extends SampleBarT

  object VarianceF extends VarianceT

  object Oplsda2D extends Oplsda2DT

  object ModelArg extends ModelArgT

  object PermuteResult extends PermuteResultT

  object VPlot extends VPlotT

  object Pca2DF extends Pca2DT

  object CcaRdaF extends CcaRdaT

  object VennF extends VennT

  object FsVennF extends FsVennT

  object VolcanoF extends VolcanoT

  object Lda extends LdaT

  object Cladogram extends CladogramT

  object Features extends FeaturesT

  object ZScoreF extends ZScoreT

  object Plsda2D extends Plsda2DT

  object ClassCountPieF extends ClassCountPieT

  object StatPieF extends StatPieT

  object Pca3DF extends Pca3DT

  object Plsda3D extends Plsda3DT

  object PathwayBubble extends PathwayBubbleT

  object PathwayBar extends PathwayBarT

  object EnrichBar extends EnrichBarT

  object Roc extends RocT

  object RocCv extends RocCvT

  object RocCvEach extends RocCvEachT

  object Pr extends PrT

  object RfPlot extends RfPlotT

  object SvmPlot extends SvmPlotT

  object BorutaBox extends BorutaBoxT

  object CorNetwork extends CorNetworkT

  object Heatmap extends HeatmapT

  object EnrichNetwork extends EnrichNetworkT

  object CorHeatmap extends CorHeatmapT

  trait SoftFT extends SoftT {

    val url: String = s"${g.jsRoutes.controllers.SoftController.analysisBefore().url.toString}?kind=${nameStr}"

  }

  trait WorkflowFT extends SoftT {

    val url: String = s"${g.jsRoutes.controllers.WorkflowController.analysisBefore().url.toString}?kind=${nameStr}"

  }

  object PlsdaSoft extends PlsdaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.plsdaBefore().url.toString
  }

  object PreDealSoft extends PreDealSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.preDealBefore().url.toString

  }

  object AnnoSoft extends AnnoSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.annoBefore().url.toString

  }

  object PcaSoft extends PcaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.pcaBefore().url.toString

  }

  object VennSoft extends VennSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.vennBefore().url.toString

  }

  object DiffAnaSoft extends DiffAnaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.diffAnaBefore().url.toString

  }

  object LefseAnaSoft extends LefseAnaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.lefseAnaBefore().url.toString

  }

  object LimmaAnaSoft extends LimmaAnaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.limmaAnaBefore().url.toString
  }

  object StampSoft extends StampSoftT with SoftFT {}

  object HorizontalBoxplotSoft extends HorizontalBoxplotSoftT with SoftFT {}

  object DiffAnaMulSoft extends DiffAnaMulSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.diffAnaMulBefore().url.toString

  }

  object CcaRdaSoft extends CcaRdaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.ccaRdaBefore().url.toString
  }

  object PreprocessSoft extends PreprocessSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.preprocessBefore().url.toString
  }

  object HeatmapSoft extends HeatmapSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.heatmapBefore().url.toString

  }

  object OplsdaSoft extends OplsdaSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.oplsdaBefore().url.toString

  }

  object BasicSoft extends BasicSoftT with SoftFT {
    override val url: String = g.jsRoutes.controllers.SoftController.basicBefore().url.toString
  }

  object ZScoreSoft extends ZScoreSoftT with SoftFT {}

  object BoxplotSoft extends BoxplotSoftT with SoftFT {}

  object ViolinPlotSoft extends ViolinPlotSoftT with SoftFT {}

  object BiomarkerSoft extends BiomarkerSoftT with SoftFT {}

  object KeggEnrichSoft extends KeggEnrichSoftT with SoftFT {}

  object IPathSoft extends IPathSoftT with SoftFT {}

  object EnrichSoft extends EnrichSoftT with SoftFT {}

  object ParCorSoft extends ParCorSoftT with SoftFT {}

  object MetMicCorSoft extends MetMicCorSoftT with SoftFT {}

  object DiagnoseSoft extends DiagnoseSoftT with SoftFT {}

  object RfSoft extends RfSoftT with SoftFT {}

  object SvmSoft extends SvmSoftT with SoftFT {}

  object BorutaSoft extends BorutaSoftT with SoftFT {}

  object DataPreprocessWorkflow extends DataPreprocessWorkflowT with WorkflowFT {}

  object FeatureSelectionWorkflow extends FeatureSelectionWorkflowT with WorkflowFT {}

  case class DiagnoseData(
      missionName: String,
      file: String,
      groupFile: String,
      scaleMethod: String = "scale",
      group: String,
      method: String
  ) extends DiagnoseDataT

  object DiagnoseData {

    implicit val rw = macroRW[DiagnoseData]

  }

  case class OplsdaData(
      missionName: String,
      file: String,
      groupFile: String,
      scaleMethod: String = "scale",
      group: String,
      vip: String,
      q2Y: String,
      q2YB: String
  ) extends OplsdaDataT

  object OplsdaData {

    implicit val rw = macroRW[OplsdaData]

  }

  case class PlsdaData(
      missionName: String,
      file: String,
      groupFile: String,
      scaleMethod: String = "scale",
      isPaired: Boolean
  ) extends PlsdaDataT

  object PlsdaData {
    implicit val rw = macroRW[PlsdaData]
  }

  trait SearchKind

  object TextSearch extends SearchKind

  object DateSearch extends SearchKind

  object NumericSearch extends SearchKind

  object DoubleSearch extends SearchKind

  object CheckboxSearch extends SearchKind

  object OnlySortSearch extends SearchKind

  trait SearchData

  case class TextSearchData(searchType: String, text: String) extends SearchData

  case class DateSearchData(startDate: String, endDate: String) extends SearchData

  case class NumericSearchData(min: String, max: String, kind: String) extends SearchData

  case class CheckboxSearchData(values: List[String]) extends SearchData

  case object OnlySortSearchData extends SearchData

  case class SortData(field: String, order: String, kind: String)

  case class ExportData(
    text: String,
    href: js.UndefOr[String] = js.undefined,
    onClick: js.UndefOr[(List[ujson.Obj], List[String]) => IO[Unit]] = js.undefined,
    disabled: Boolean = false
  )

}
